﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EmotionRecognitionEntities;
using EmotionRecognitionDB;
using System.Windows.Forms;

namespace EmotionRecognitionManager
{
    public class Adaptation
    {

        public Adaptation() { }

        #region Step 1 - Creation of containers for process variables
        //Step 1 in the algorithm- Creation of lists
        //Solution
        //Chunk --   And All cases that belongs to the chunk that retrievd by Retrieval algorithm
        Dictionary<Chunk, Case> solutions = new Dictionary<Chunk, Case>();
        //List for Saving InputAUList
        List<int> savedAuList = new List<int>();
        //InputAUlist
        List<int> inputAuList = new List<int>();
        //will hold All cases of all chunks - wil be filled after step 2
        List<Case> casesList = new List<Case>();
        // will be used in Step 2
        List<Case> IndexcasesList = new List<Case>();
        //BestCases in Step 3
        List<Case> BestCases = new List<Case>();
        //chunks Id list
        List<int> chunkId = new List<int>();
        //Full chunks list
        List<Chunk> chunks = new List<Chunk>(); // contains the labels inside
        #endregion

        #region Run retrieval algorithm

        public ReplyMsg ExecuteAdaptationAlgorithm(Dictionary<Chunk, Case> solutions, string chunkFeedbackName, bool secondRun)
        {
            //create chunk if not exists and returns its id
            //Step 1 - in the algorithm
            Chunk chunkFeedback = new Chunk(ChunkFeedbackHandle(chunkFeedbackName),chunkFeedbackName);
            foreach(Case caseAdapt in solutions.Values)
            {
                //add case to chunk checks if needed to be index as standalone one -> try to do standalone check for combinations standalones (1+2)->standalone , (1+2+3) ->not index!!!
                //Step 2 - in the algorithm
                CaseInChunk(chunkFeedback, caseAdapt);
                 
            }

            DBQueries.SetIndexCases(secondRun);

            return new ReplyMsg(true);
        }

        //check if chunk empty(if case count == 0)
            //false - //isIndex == 0, check if case exist (if isIndex == 0, keep original index value)
                        //true  - check if case_chunkid == chunk
                            //true - (isIncTypicality == 1 , KEEP ORIGINAL TYPICALITY)
                            //false - (isIncTypicality == 0 ,typicality = 1 -> reset)
                        //false - CaseInChunk(Case, Chunk, isIncTypicality, isIndex)
            //true  - //isIndex == 1, check if case exist (set case as index)
                            //(isIncTypicality == 0 ,typicality = 1 -> reset)
                        //CaseInChunk(Case, Chunk, isIncTypicality, isIndex)

        private void CaseInChunk(Chunk chunkFeedback, Case caseAdapt)
        {
            ReplyMsg msg = DBQueries.CheckChunkSize(chunkFeedback);
            bool isIncTypicality,isIndex;
            if (msg.MessageState == true)// if chunk empty no matter the case is stdalone the case will be index of the currently empty chunk
            {
                if ((int)msg.ParamArray[0] == 0) //
                    isIndex = true;
                else
                    isIndex = false;
            }
            else throw new Exception("DBQueries.IsChunkEmpty(chunkFeedback) Error");
            if (caseAdapt.ChunkID == chunkFeedback.ChunkId)
                isIncTypicality = true;
            else
                isIncTypicality = false;
            //case (1,2,3) -> happy
            //retrieval -> (1+2+3) ->happy dont know if exist in db

            //feedback ->angry
            //adaptation -> (1+2+3 , typ =1) ->angry exist in db (for dup get id)
            //add to angry (1+2+3 , typ =1)

            //Check if case exists

            if (caseAdapt.ExistsInDb == false) //not sure if case exist or not
            {
                ReplyMsg msg1 = DBQueries.IfCaseExistInDBbyAUs(caseAdapt); //check if case exists by aus if so return id if not false return (msgstate, exists:bool, id if exists true)

                if (msg1.MessageState == true)
                {//
                    if ((Boolean)msg1.ParamArray[0] == true)
                        //Update case 
                        DBQueries.UpadteExisitingCaseWithChunkInDB((int)msg1.ParamArray[1], 1, (isIndex == true) ? true : caseAdapt.IsIndex, chunkFeedback.ChunkId);
                    else
                        //Create new case
                        DBQueries.CreateNewCase(DBQueries.GetLastCaseID(), 1, (isIndex == true) ? true : caseAdapt.IsIndex, chunkFeedback.ChunkId, 2, caseAdapt.AuList);
                }

            }
            else
                DBQueries.UpadteExisitingCaseWithChunkInDB(caseAdapt.CaseID, (isIncTypicality == true) ? caseAdapt.Typicality : 1, (isIndex == true) ? true : caseAdapt.IsIndex, chunkFeedback.ChunkId);
        }
        
        //check if chunk exist
        //false - build new empty chunk with label
        //return chunk id

        private int ChunkFeedbackHandle(string chunkFeedbackName)
        {
            ReplyMsg msg = DBQueries.CreateNewChunk(chunkFeedbackName);
            if (msg.MessageState == true)
                return (int)msg.ParamArray[0];
            MessageBox.Show("DBQueries.CreateNewChunk failed");
            return -1;
        }
    }
}
        #endregion

